#ifndef MAPFORM_H_
#define MAPFORM_H_

#include <FLocations.h>
#include <FBase.h>
#include <FUi.h>
#include <FGraphics.h>
#include "OpennavMapServiceProvider.h"
#include "OpennavReverseGeocodingServiceProvider.h"
#include "OpennavMap.h"
#include "BadaImage.h"

using namespace opennav;

class MapForm :
	public Osp::Ui::Controls::Form,
	public Osp::Ui::IActionEventListener,
	public Osp::Locations::ILocationListener,
	public Osp::Ui::ITouchEventListener,
	public Osp::Ui::IOrientationEventListener,
	public OpennavMapServiceProvider::IOpennavMapProviderListener,
	public IOpennavReverseGeocodeListener
	//public OpennavMap::IOpennavMapListener
	{

public:
	MapForm();
	virtual ~MapForm();
	result Construct(OpennavMap* map);
protected:
	Osp::Ui::Controls::Label *__pLabelStreet;
	Osp::Ui::Controls::OptionMenu *__pOptionMenu;
	static const int ID_ON_OPTION_MENU = 200;
	static const int ID_OPTION_CENTER_GPS = 201;
	static const int ID_OPTION_NORTH = 202;
	static const int ID_OPTION_HACK = 203;
	static const int ID_SOFTKEY_BACK = 101;

public:
	virtual result OnInitializing(void);
	virtual result OnTerminating(void);
	virtual result OnDraw(void);
	virtual void OnActionPerformed(const Osp::Ui::Control& source, int actionId);

	virtual void OnTouchDoublePressed(const Osp::Ui::Control &source, const Osp::Graphics::Point &currentPosition, const Osp::Ui::TouchEventInfo &touchInfo);
	virtual void OnTouchFocusIn(const Osp::Ui::Control &source, const Osp::Graphics::Point &currentPosition, const Osp::Ui::TouchEventInfo &touchInfo);
	virtual void OnTouchFocusOut(const Osp::Ui::Control &source, const Osp::Graphics::Point &currentPosition, const Osp::Ui::TouchEventInfo &touchInfo);
	virtual void OnTouchLongPressed(const Osp::Ui::Control &source, const Osp::Graphics::Point &currentPosition, const Osp::Ui::TouchEventInfo &touchInfo);
	virtual void OnTouchMoved(const Osp::Ui::Control &source, const Osp::Graphics::Point &currentPosition, const Osp::Ui::TouchEventInfo &touchInfo);
	virtual void OnTouchPressed(const Osp::Ui::Control &source, const Osp::Graphics::Point &currentPosition, const Osp::Ui::TouchEventInfo &touchInfo);
	virtual void OnTouchReleased(const Osp::Ui::Control &source, const Osp::Graphics::Point &currentPosition, const Osp::Ui::TouchEventInfo &touchInfo);

	// IOrientationEventListener
	virtual void OnOrientationChanged(const Osp::Ui::Control &source, Osp::Ui::OrientationStatus orientationStatus);

	//ILocationListener method
	void OnLocationUpdated(Osp::Locations::Location& location);
	void OnProviderStateChanged(Osp::Locations::LocProviderState newState);

	//IOpennavMapProviderListener
	void OnMapRequestFinished(OpennavMapSection* section, int requestId);

	//IOpennavReverseGeocodeListener
	void OnReverseGeocodeResultReceived(opennav::Road& road, opennav::RoadSegment& roadSegment, opennav::RoadJunction& nextJunction, Osp::Locations::Coordinates& coordinate);
	void OnNoReverseGeocodeResultReceived();

private:
	enum
	{
		TOUCH_FLAG_MOVED = 0x01,
		TOUCH_FLAG_DOUBLE_TAP = 0x02
	};
private:
	void ChangeMap(const Osp::Ui::Control& source);
	void ChangeMap(const Osp::Base::Collection::IList& oldTouchInfo, const Osp::Base::Collection::IList& newTouchInfo);
	void PanMap(int dx, int dy);
	void ZoomMap(float factor);
	void UpdateMap();
	void UpdateRoad();

	// TODO: brauchen wir noch??
	Osp::Graphics::Rectangle							__clientRect;
	Osp::Base::Collection::IList*						__pLastTouchInfoList;
	int													__touchFlags;
	long long											__lastDoubleTapTick;
	Osp::Graphics::Point lastZoomTouch1, lastZoomTouch2;

	bool __isLocationUpdated;
	bool __isRequestLastLocation;
	bool __isValidLocation;
	int __interval;
	long long int __timestamp;

	double __latitude;
	double __longitude;
	float __altitude;
	float __speed;
	float __course;

	int __errorCode;
	Osp::Locations::LocationProvider* __pLocationProvider;
	const Osp::Locations::SatelliteInfo* __pSatelliteInfo;

	OpennavMap* __pMap;
	OpennavMapServiceProvider* __pMapProvider;
	OpennavReverseGeocodingServiceProvider* __pReverseGeocodingProvider;
	OpennavMapSection* __pCurrentSection;
	Mutex* __pCurrentSectionLock;

	Osp::Graphics::Point __pan;
	float __scale;

	bool __touch;

	bool __follow;

	float __azimuth;

	float hack;

	opennav::Road* __pCurrentRoad;
	opennav::RoadSegment* __pCurrentRoadSegment;
	Osp::Locations::Coordinates* __pCurrentResolvedCoordinate;
	Mutex* __pCurrentRoadLock;

};

#endif /* MAPFORM_H_ */
